package com.lysj.bhp.user.util;

import com.lysj.bhp.investment.domain.Reward;
import com.lysj.bhp.investment.repository.RewardRepository;
import com.lysj.bhp.system.base.BaseConst;
import com.lysj.bhp.user.repository.UserRepository;
import com.lysj.bhp.util.random.FormatUtil;
import com.lysj.bhp.util.web.ParamUtil;
import com.lysj.bhp.util.web.Resp;
import com.lysj.bhp.wallet.controller.EthereumWalletController;
import com.lysj.bhp.wallet.domain.BhpcWallet;
import com.lysj.bhp.wallet.domain.BitCoinAddress;
import com.lysj.bhp.wallet.domain.BitCoinWallet;
import com.lysj.bhp.wallet.domain.EthereumWallet;
import com.lysj.bhp.wallet.repository.BhpcWalletRepository;
import com.lysj.bhp.wallet.repository.BitcoinAddressRepository;
import com.lysj.bhp.wallet.repository.BitcoinWalletRepository;
import com.lysj.bhp.wallet.repository.EthereumWalletRepository;
import com.lysj.bhp.wallet.util.BlockChainUtil;
import info.blockchain.api.wallet.entity.Address;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.web3j.crypto.WalletUtils;

import javax.annotation.Resource;
import java.io.File;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.Map;

@Component
public class MyWallet {

    private Logger logger = LoggerFactory.getLogger(EthereumWalletController.class);

    @Resource
    public UserRepository userRepository;
    @Resource
    public BhpcWalletRepository bhpcWalletRepository;
    @Resource
    public EthereumWalletRepository ethereumWalletRepository;
    @Resource
    public BitcoinWalletRepository bitcoinWalletRepository;
    @Resource
    public RewardRepository rewardRepository;
    @Resource
    public BitcoinAddressRepository bitcoinAddressRepository;

    public BhpcWallet createBhpcWallet(Long userId) throws Exception {
        String password = ParamUtil.uuid();
        String keystoreFilename = WalletUtils.generateFullNewWalletFile(password, new File(BaseConst.KEY_STORE_DIR));

        String[] addressArray = keystoreFilename.split("--");
        String address = addressArray[2].substring(0, 40);

        BhpcWallet bhpcWallet = new BhpcWallet();
        bhpcWallet.setKeystore(keystoreFilename);
        bhpcWallet.setPassword(password);
        bhpcWallet.setUserId(userId);
        bhpcWallet.setAddress(address);
        bhpcWallet.setBalance(BigDecimal.ZERO);
        bhpcWallet.setFreezeBalance(BigDecimal.ZERO);
        bhpcWallet.setAvailBalance(BigDecimal.ZERO);
        bhpcWallet.setBookKeepBalance(BigDecimal.ZERO);
        //------------增加钱包的抵押冻结资产----------------
        bhpcWallet.setPledgeFreezeBalance(BigDecimal.ZERO);
        logger.info(bhpcWallet.toString());
        bhpcWalletRepository.save(bhpcWallet);
        return bhpcWallet;
    }


    public Resp createEthWallet(Long userId) throws Exception {
        String password = ParamUtil.uuid();
        String keystoreFilename = WalletUtils.generateFullNewWalletFile(password, new File(BaseConst.KEY_STORE_DIR));

        String[] addressArray = keystoreFilename.split("--");
        String address = addressArray[2].substring(0, 40);

        EthereumWallet ethereum = new EthereumWallet();
        ethereum.setKeystore(keystoreFilename);
        ethereum.setPassword(password);
        ethereum.setUserId(userId);
        ethereum.setAddress(address);
        ethereum.setBalance(BigDecimal.ZERO);
        ethereum.setFreezeBalance(BigDecimal.ZERO);
        ethereum.setAvailBalance(BigDecimal.ZERO);
        ethereum.setBookKeepBalance(BigDecimal.ZERO);
        //------------增加钱包的抵押冻结资产----------------
        ethereum.setPledgeFreezeBalance(BigDecimal.ZERO);
        logger.info(ethereum.toString());
        ethereumWalletRepository.save(ethereum);
        return new Resp(ethereum);
    }


    public Resp createBitWallet(Long userId, String email) throws Exception {
        String password = ParamUtil.uuid();
        Map<String, String> resultMap = BlockChainUtil.createWallet(password, email);
        if (resultMap == null || resultMap.size() == 0) {
            return new Resp(Resp.INNER_ERROR, "创建钱包失败,请重试!");
        }
        String guid = resultMap.get("guid");
        if (ParamUtil.isBlack(guid)) {
            return new Resp(Resp.INNER_ERROR, "创建钱包失败,请重试!");
        }
        BitCoinWallet bitCoinWallet = new BitCoinWallet();
        bitCoinWallet.setUserId(userId);
        bitCoinWallet.setEmail(email);
        bitCoinWallet.setPassword(password);
        bitCoinWallet.setGuid(guid);
        bitCoinWallet.setHdAddress(resultMap.get("address"));
        bitCoinWallet.setLabel(resultMap.get("label"));
        bitCoinWallet.setBalance(BigDecimal.ZERO);
        bitCoinWallet.setFreezeBalance(BigDecimal.ZERO);
        bitCoinWallet.setAvailBalance(BigDecimal.ZERO);
        bitCoinWallet.setBookKeepBalance(BigDecimal.ZERO);
        //------------增加钱包的抵押冻结资产----------------
        bitCoinWallet.setPledgeFreezeBalance(BigDecimal.ZERO);

        //创建一个新的比特币地址
        String lable = null;
        try {
            lable = FormatUtil.dateToString(new Date());
        } catch (Exception e) {
            e.printStackTrace();
        }
        Address address = BlockChainUtil.createAddress(bitCoinWallet.getGuid(), bitCoinWallet.getPassword(), lable);
        if (address == null) {
            return new Resp(Resp.INNER_ERROR, "创建地址失败,请重试!");
        }

        BitCoinAddress bitCoinAddress = new BitCoinAddress();
        bitCoinAddress.setUserId(userId);
        bitCoinAddress.setBitcoinWalletId(bitCoinWallet.getBitcoinWalletId());

        bitCoinAddress.setAddress(address.getAddress());
        bitCoinAddress.setLabel(lable);
        bitCoinAddress.setBalance(0);
        bitCoinAddress.setTotalReceived(0);

        logger.info("创建了一个比特币地址--address:" + address.getAddress());
        bitcoinAddressRepository.save(bitCoinAddress);

        bitCoinWallet.setLastAddress(bitCoinAddress.getAddress());
        bitcoinWalletRepository.save(bitCoinWallet);

        return new Resp(bitCoinWallet);
    }


    public Resp createReward(Long userId) throws Exception {
        Reward reward = new Reward();
        reward.setUserId(userId);
        reward.setType(100);
        reward.setBalance(new BigDecimal(BigInteger.ZERO));
        reward.setAvailBalance(new BigDecimal(BigInteger.ZERO));
        reward.setFreezeBalance(new BigDecimal(BigInteger.ZERO));
        rewardRepository.save(reward);
        return new Resp(reward);
    }
}
